using System.Xml;

namespace Voodoo.Sauce.Internal.Utils
{
	public static class ManifestUtils
	{
		private const string DESTINATION_APPLICATION_MANIFEST_PATH = "Assets/Plugins/Android/AndroidManifest.xml";

		private static void AddPermission(XmlDocument document, XmlNode sourceNode)
		{
			XmlElement documentElement = document.DocumentElement;
			if (documentElement == null)
			{
				return;
			}
			foreach (XmlNode childNode in documentElement.ChildNodes)
			{
				if (childNode.Name == "uses-permission")
				{
					string namespaceOfPrefix = childNode.GetNamespaceOfPrefix("android");
					if (GetAndroidElementName(childNode, namespaceOfPrefix) == GetAndroidElementName(sourceNode, namespaceOfPrefix))
					{
						return;
					}
				}
			}
			documentElement.AppendChild(document.ImportNode(sourceNode, deep: true));
		}

		private static void AddChildNode(XmlDocument document, XmlNode parent, XmlNode node)
		{
			if (parent != null && node != null && !FindElementWithAndroidName(parent, node))
			{
				parent.AppendChild(document.ImportNode(node, deep: true));
			}
		}

		private static XmlNode FindChildNode(XmlNode parent, XmlNode child)
		{
			for (XmlNode xmlNode = parent.FirstChild; xmlNode != null; xmlNode = xmlNode.NextSibling)
			{
				if (xmlNode.Name.Equals(child.Name))
				{
					return xmlNode;
				}
			}
			return null;
		}

		private static bool FindElementWithAndroidName(XmlNode parent, XmlNode child)
		{
			string namespaceOfPrefix = parent.GetNamespaceOfPrefix("android");
			string androidElementName = GetAndroidElementName(child, namespaceOfPrefix);
			if (androidElementName != null)
			{
				for (XmlNode xmlNode = parent.FirstChild; xmlNode != null; xmlNode = xmlNode.NextSibling)
				{
					if (GetAndroidElementName(xmlNode, namespaceOfPrefix) == androidElementName)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static string GetAndroidElementName(XmlNode node, string namespaceOfPrefix)
		{
			if (!(node is XmlElement xmlElement))
			{
				return null;
			}
			return xmlElement.GetAttribute("name", namespaceOfPrefix);
		}

		private static void save(string manifestPath, XmlDocument document)
		{
			XmlWriterSettings settings = new XmlWriterSettings
			{
				Indent = true,
				IndentChars = "  ",
				NewLineChars = "\r\n",
				NewLineHandling = NewLineHandling.Replace
			};
			using XmlWriter w = XmlWriter.Create(manifestPath, settings);
			document.Save(w);
		}
	}
}
